#include "Aestrella.h"

Aestrella::Aestrella(int queueSize) : open(queueSize) {

}

CNodo* Aestrella::buscar(CNodo* s0, Heuristica* heu) {
    CNodo *c;
    const CasilleroA *casillero = static_cast<const CasilleroA*> (s0->Casillas());
    s0->SetOpen(true);
    s0->SetG(0);
    s0->SetH(heu->h(s0));
    nodosExp.insert(make_pair(*casillero, *s0));
    hash_A::iterator it = nodosExp.find(*casillero);
    open.insert(&(it->second));
    int oldG;
    CNodo* suc;
    while (c = open.first()) {
        if (c->EsGoal()) {
            return c;
        }
        c->unlink();
        c->SetOpen(false);
        oldG = c->GetG();
        for (int i = 0; i < 4; i++) {
            suc = c->GenerarSucesor(CNodo::operadores[i]);
            if (suc) {
                casillero = static_cast<const CasilleroA*> (suc->Casillas());
                it = nodosExp.find(*casillero);
                if (it == nodosExp.end()) {
                    suc->SetOpen(true);
                    suc->SetG(oldG + 1);
                    suc->SetH(heu->h(suc));
                    nodosExp.insert(make_pair(*casillero, *suc));
                    it = nodosExp.find(*casillero);
                    open.insert(&(it->second));
                } else if (((CNodo) (it->second)).IsOpen() && ((CNodo) (it->second)).GetG() > (oldG + 1)) {
                    open.reorder(&(it->second), oldG + 1, heu->h(suc));
                }
                delete suc;
            }
        }
    }
}
